package handler

import (
    "fcs-api/src/app/model"
    "fcs-api/src/app/utils"
    "fcs-api/src/client"
    k8s "fcs-api/src/client/kubernetes"
    "net/http"

    "git.inspur.com/x/auditlog"
    commonError "git.inspur.com/x/common/error"
    "git.inspur.com/x/common/filters"
    commonFilter "git.inspur.com/x/common/filters"
    "git.inspur.com/x/common/loggerfactory"
    adapter "git.inspur.com/x/iam-adapter-go"
    iamClient "git.inspur.com/x/iam-adapter-go/client"
    "git.inspur.com/x/iam-adapter-go/resource"
    "github.com/emicklei/go-restful"
    "k8s.io/client-go/rest"
    "k8s.io/client-go/tools/clientcmd"
)

const (
    FcsErrorCodeSuffix = "201"

    IamServiceFcs              = "fcs"
    IamResourceFcsGroup        = "fcs-group"
    IamResourceFcsFunction     = "fcs-function"
    IamResourceFcsTrigger      = "fcs-trigger"
    InternalServerErrorCode    = ".999500"
    InternalServerErrorMessage = "内部系统错误"
)

// InstallFilters installs defined filter for given web service
func InstallFilters(ws *restful.WebService) {
    ws.Filter(filters.ExceptionFilter)
    ws.Filter(filters.RequestIdFilter)
    ws.Filter(filters.PreHeaderFilter)
    ws.Filter(adapter.WhiteListFilter)
    ws.Filter(adapter.AuthenticationFilter)
    ws.Filter(adapter.AuthorizationFilter)
    ws.Filter(adapter.RegionFilter)
    ws.Filter(auditlog.AuditFilter)
}

var logger = loggerfactory.GetLogger()

type APIHandler struct {
    ClusterManager client.ClusterClientManager
    InvokeChan     chan *model.Invoke
}

func NewApplicationHandler(apiHandler *APIHandler) *restful.WebService {
    apiAppV1Ws := new(restful.WebService)
    apiAppV1Ws.Consumes(restful.MIME_JSON).Produces(restful.MIME_JSON)

    InstallFilters(apiAppV1Ws)
    apiAppV1Ws.Path("/ifcs/v1")

    iamClient.PermissionContexts["handleHealth"] = resource.PermissionContext{LoginAccess: true}

    // ---------- 应用相关接口 ----------
    // 创建应用
    apiAppV1Ws.Route(
        apiAppV1Ws.POST("/groups").
            To(apiHandler.handleCreateGroup).
            Doc("创建应用").
            Writes(model.Group{}).
            Returns(200, "OK", model.Group{}))
    iamClient.PermissionContexts["handleCreateGroup"] = resource.PermissionContext{
        Service:      IamServiceFcs,
        ResourceType: IamResourceFcsGroup,
        Action:       "CreateGroup",
        RecordOps:    true,
    }
    // 更新应用
    apiAppV1Ws.Route(
        apiAppV1Ws.PUT("/groups/{groupId}").
            To(apiHandler.handleUpdateGroup).
            Doc("更新应用").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Writes(model.Group{}).
            Returns(200, "OK", model.Group{}))
    iamClient.PermissionContexts["handleUpdateGroup"] = resource.PermissionContext{
        Service:          IamServiceFcs,
        ResourceType:     IamResourceFcsGroup,
        Action:           "UpdateGroup",
        Resource:         "{groupId}",
        ResourceFunction: getGroupById,
        RecordOps:        true,
    }
    // 删除应用
    apiAppV1Ws.Route(
        apiAppV1Ws.DELETE("/groups/{groupId}").
            To(apiHandler.handleDeleteGroup).
            Doc("删除应用").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Returns(200, "OK", nil))
    iamClient.PermissionContexts["handleDeleteGroup"] = resource.PermissionContext{
        Service:          IamServiceFcs,
        ResourceType:     IamResourceFcsGroup,
        Action:           "DeleteGroup",
        Resource:         "{groupId}",
        ResourceFunction: getGroupById,
        RecordOps:        true,
    }
    // 获取应用列表
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/groups").
            To(apiHandler.handleGetGroupList).
            Doc("获取应用列表").
            Returns(200, "OK", []model.Group{}))
    iamClient.PermissionContexts["handleGetGroupList"] = resource.PermissionContext{
        Service:      IamServiceFcs,
        ResourceType: IamResourceFcsGroup,
        Action:       "ListGroup",
    }
    // 获取应用详情
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/groups/{groupId}").
            To(apiHandler.handleGetGroupDetail).
            Doc("获取应用详情").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Returns(200, "OK", model.Group{}))
    iamClient.PermissionContexts["handleGetGroupDetail"] = resource.PermissionContext{
        Service:          IamServiceFcs,
        ResourceType:     IamResourceFcsGroup,
        Action:           "GetGroup",
        Resource:         "{groupId}",
        ResourceFunction: getGroupById,
    }
    // 检查应用名称是否存在
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/groups/action/exist").
            To(apiHandler.handleCheckGroupExist).
            Doc("检查应用名称是否存在").
            Returns(200, "OK", nil))
    iamClient.PermissionContexts["handleCheckGroupExist"] = resource.PermissionContext{
        LoginAccess: true,
    }

    // ---------- 函数相关接口 ----------
    // 创建函数
    apiAppV1Ws.Route(
        apiAppV1Ws.POST("/groups/{groupId}/functions").
            To(apiHandler.handleCreateFunction).
            Doc("创建函数").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Writes(model.FuncInfo{}).
            Returns(200, "OK", model.FuncInfo{}))
    iamClient.PermissionContexts["handleCreateFunction"] = resource.PermissionContext{
        Service:      IamServiceFcs,
        ResourceType: IamResourceFcsFunction,
        Action:       "CreateFunction",
        RecordOps:    true,
    }
    // 复制函数
    apiAppV1Ws.Route(
        apiAppV1Ws.POST("/groups/{groupId}/functions/{functionId}/action/copy").
            To(apiHandler.handleCopyFunction).
            Doc("复制函数").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Writes(model.FuncInfo{}).
            Returns(200, "OK", model.FuncInfo{}))
    iamClient.PermissionContexts["handleCopyFunction"] = resource.PermissionContext{
        LoginAccess: true,
        RecordOps:   true,
    }
    // 更新函数
    apiAppV1Ws.Route(
        apiAppV1Ws.PUT("/groups/{groupId}/functions/{functionId}").
            To(apiHandler.handleUpdateFunction).
            Doc("更新函数").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Writes(model.FuncInfo{}).
            Returns(200, "OK", model.FuncInfo{}))
    iamClient.PermissionContexts["handleUpdateFunction"] = resource.PermissionContext{
        Service:          IamServiceFcs,
        ResourceType:     IamResourceFcsFunction,
        Action:           "UpdateFunction",
        Resource:         "{functionId}",
        ResourceFunction: getFunctionById,
        RecordOps:        true,
    }

    // 更新函数层
    apiAppV1Ws.Route(
        apiAppV1Ws.PUT("/groups/{groupId}/functions/{functionId}/layer").
            To(apiHandler.handleUpdateFunctionLayer).
            Doc("更新函数层").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Writes(model.FuncInfo{}).
            Returns(200, "OK", model.FuncInfo{}))
    iamClient.PermissionContexts["handleUpdateFunctionLayer"] = resource.PermissionContext{LoginAccess: true}
    // 删除函数
    apiAppV1Ws.Route(
        apiAppV1Ws.DELETE("/groups/{groupId}/functions/{functionId}").
            To(apiHandler.handleDeleteFunction).
            Doc("删除函数").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Returns(200, "OK", nil))
    iamClient.PermissionContexts["handleDeleteFunction"] = resource.PermissionContext{
        Service:          IamServiceFcs,
        ResourceType:     IamResourceFcsFunction,
        Action:           "DeleteFunction",
        Resource:         "{functionId}",
        ResourceFunction: getFunctionById,
        RecordOps:        true,
    }
    // 获取函数列表
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/functions").
            To(apiHandler.handleGetFunctionList).
            Doc("获取所有函数列表").
            Returns(200, "OK", []model.FuncInfo{}))
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/groups/{groupId}/functions").
            To(apiHandler.handleGetFunctionList).
            Doc("获取应用下函数列表").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Returns(200, "OK", []model.FuncInfo{}))
    iamClient.PermissionContexts["handleGetFunctionList"] = resource.PermissionContext{
        Service:      IamServiceFcs,
        ResourceType: IamResourceFcsFunction,
        Action:       "ListFunction",
    }
    // 获取函数版本详情
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/groups/{groupId}/functions/{functionId}/versions/{versionName}").
            To(apiHandler.handleGetFunctionDetail).
            Doc("获取函数版本详情").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Param(apiAppV1Ws.PathParameter("versionName", "版本名称")).
            Returns(200, "OK", model.FuncInfo{}))
    iamClient.PermissionContexts["handleGetFunctionDetail"] = resource.PermissionContext{
        Service:          IamServiceFcs,
        ResourceType:     IamResourceFcsFunction,
        Action:           "GetFunction",
        Resource:         "{functionId}",
        ResourceFunction: getFunctionById,
    }
    // 调用函数
    apiAppV1Ws.Route(
        apiAppV1Ws.POST("/groups/{groupId}/functions/{functionId}/versions/{versionName}/invoke").
            To(apiHandler.handleInvokeFunction).
            Doc("调用函数").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Param(apiAppV1Ws.PathParameter("versionName", "版本名称")).
            Writes(model.Invoke{}).
            Returns(200, "OK", model.Invoke{}))
    iamClient.PermissionContexts["handleInvokeFunction"] = resource.PermissionContext{
        Service:          IamServiceFcs,
        ResourceType:     IamResourceFcsFunction,
        Action:           "InvokeFunction",
        Resource:         "{functionId}",
        ResourceFunction: getFunctionById,
        RecordOps:        true,
    }
    // 检查函数名称是否存在
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/groups/{groupId}/functions/action/exist").
            To(apiHandler.handleGetFunctionExist).
            Doc("检查函数名称是否存在").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Returns(200, "OK", nil))
    iamClient.PermissionContexts["handleGetFunctionExist"] = resource.PermissionContext{
        LoginAccess: true,
    }
    // 下载用户函数代码
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/groups/{groupId}/functions/{functionId}/versions/{versionName}/code/download").
            To(apiHandler.handleDownloadUserCode).
            Doc("下载用户函数代码").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Param(apiAppV1Ws.PathParameter("versionName", "版本名称")).
            Returns(200, "OK", model.CodeInfo{}))
    iamClient.PermissionContexts["handleDownloadUserCode"] = resource.PermissionContext{
        Service:          IamServiceFcs,
        ResourceType:     IamResourceFcsFunction,
        Action:           "DownloadCode",
        Resource:         "{functionId}",
        ResourceFunction: getFunctionById,
        RecordOps:        true,
    }
    // 下载函数代码
    apiAppV1Ws.Route(
        apiAppV1Ws.POST("/code/action/download").
            To(apiHandler.handleDownloadCode).
            Doc("下载函数代码").
            Returns(200, "OK", model.CodeInfo{}))
    iamClient.PermissionContexts["handleDownloadCode"] = resource.PermissionContext{
        LoginAccess: true,
    }
    // 上传函数代码
    apiAppV1Ws.Route(
        apiAppV1Ws.POST("/groups/{groupId}/functions/{functionId}/versions/{versionName}/code/upload").
            To(apiHandler.handleUploadCode).
            Doc("上传函数代码").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Param(apiAppV1Ws.PathParameter("versionName", "版本名称")).
            Writes(model.CodeInfo{}).
            Returns(200, "OK", nil))
    iamClient.PermissionContexts["handleUploadCode"] = resource.PermissionContext{
        Service:          IamServiceFcs,
        ResourceType:     IamResourceFcsFunction,
        Action:           "UploadCode",
        Resource:         "{functionId}",
        ResourceFunction: getFunctionById,
        RecordOps:        true,
    }

    // 上传层代码
    apiAppV1Ws.Route(
        apiAppV1Ws.POST("/layers/{layerId}/code/upload").
            To(apiHandler.handleUploadLayer).
            Doc("上传层代码").
            Param(apiAppV1Ws.PathParameter("layerId", "层id")).
            Returns(200, "OK", nil))
    iamClient.PermissionContexts["handleUploadLayer"] = resource.PermissionContext{
        LoginAccess: true,
    }

    // 下载用户层代码
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/layers/{layerId}/versions/{versionName}/code/download").
            To(apiHandler.handleDownloadLayer).
            Doc("下载层代码").
            Param(apiAppV1Ws.PathParameter("layerId", "层id")).
            Param(apiAppV1Ws.PathParameter("versionName", "版本名称")).
            Returns(200, "OK", model.LayerFileInfo{}))
    iamClient.PermissionContexts["handleDownloadLayer"] = resource.PermissionContext{
        LoginAccess: true,
    }

    // 获取函数调用日志
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/groups/{groupId}/functions/{functionId}/logs").
            To(apiHandler.handleGetLog).
            Doc("取函数调用日志").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Returns(200, "OK", model.LogResult{}))
    iamClient.PermissionContexts["handleGetLog"] = resource.PermissionContext{
        Service:          IamServiceFcs,
        ResourceType:     IamResourceFcsFunction,
        Action:           "GetFunctionLog",
        Resource:         "{functionId}",
        ResourceFunction: getFunctionById,
    }
    // 获取函数监控指标
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/groups/{groupId}/functions/{functionId}/metrics").
            To(apiHandler.handleGetMetrics).
            Doc("获取函数监控指标").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Returns(200, "OK", map[string]interface{}{}))
    iamClient.PermissionContexts["handleGetMetrics"] = resource.PermissionContext{
        Service:          IamServiceFcs,
        ResourceType:     IamResourceFcsFunction,
        Action:           "GetFunctionMetric",
        Resource:         "{functionId}",
        ResourceFunction: getFunctionById,
    }
    // 获取函数监控指标概览-应用
    // TODO: 需要处理好主用户、子用户看到的函数和调用记录与汇总数据展示之间的关系
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/functions/metrics").
            To(apiHandler.handleGetRegionMetrics).
            Doc("获取函数监控指标概览").
            Returns(200, "OK", model.RegionMetricResult{}))
    iamClient.PermissionContexts["handleGetRegionMetrics"] = resource.PermissionContext{
        Service:      IamServiceFcs,
        ResourceType: IamResourceFcsGroup,
        Action:       "ListGroup",
    }
    // 获取函数监控指标概览-函数
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/functions/metrics-functions").
            To(apiHandler.handleGetRegionMetricsFunction).
            Doc("获取函数监控指标概览").
            Returns(200, "OK", model.RegionMetricFunctionResult{}))
    iamClient.PermissionContexts["handleGetRegionMetricsFunction"] = resource.PermissionContext{
        Service:      IamServiceFcs,
        ResourceType: IamResourceFcsFunction,
        Action:       "ListFunction",
    }
    // ---------- 触发器相关接口 ----------
    // 创建触发器
    apiAppV1Ws.Route(
        apiAppV1Ws.POST("/groups/{groupId}/functions/{functionId}/triggers").
            To(apiHandler.handleCreateTrigger).
            Doc("创建触发器").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Writes(model.Trigger{}).
            Returns(200, "OK", model.Trigger{}))
    iamClient.PermissionContexts["handleCreateTrigger"] = resource.PermissionContext{
        Service:      IamServiceFcs,
        ResourceType: IamResourceFcsTrigger,
        Action:       "CreateTrigger",
        RecordOps:    true,
    }
    // 更新触发器
    apiAppV1Ws.Route(
        apiAppV1Ws.PUT("/groups/{groupId}/functions/{functionId}/triggers/{triggerId}").
            To(apiHandler.handleUpdateTrigger).
            Doc("更新触发器").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Param(apiAppV1Ws.PathParameter("triggerId", "触发器id")).
            Writes(model.Trigger{}).
            Returns(200, "OK", model.Trigger{}))
    iamClient.PermissionContexts["handleUpdateTrigger"] = resource.PermissionContext{
        Service:          IamServiceFcs,
        ResourceType:     IamResourceFcsTrigger,
        Action:           "UpdateTrigger",
        Resource:         "{triggerId}",
        ResourceFunction: getTriggerById,
        RecordOps:        true,
    }
    // 删除触发器
    apiAppV1Ws.Route(
        apiAppV1Ws.DELETE("/groups/{groupId}/functions/{functionId}/triggers/{triggerId}").
            To(apiHandler.handleDeleteTrigger).
            Doc("删除触发器").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Param(apiAppV1Ws.PathParameter("triggerId", "触发器id")).
            Returns(200, "OK", nil))
    iamClient.PermissionContexts["handleDeleteTrigger"] = resource.PermissionContext{
        Service:          IamServiceFcs,
        ResourceType:     IamResourceFcsTrigger,
        Action:           "DeleteTrigger",
        Resource:         "{triggerId}",
        ResourceFunction: getTriggerById,
        RecordOps:        true,
    }
    // 获取触发器列表
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/groups/{groupId}/functions/{functionId}/triggers").
            To(apiHandler.handleGetTriggerList).
            Doc("获取触发器列表").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Returns(200, "OK", []model.Group{}))
    iamClient.PermissionContexts["handleGetTriggerList"] = resource.PermissionContext{
        Service:      IamServiceFcs,
        ResourceType: IamResourceFcsTrigger,
        Action:       "ListTrigger",
    }
    // 获取触发器详情
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/groups/{groupId}/functions/{functionId}/triggers/{triggerId}").
            To(apiHandler.handleGetTriggerDetail).
            Doc("获取触发器详情").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Param(apiAppV1Ws.PathParameter("triggerId", "触发器id")).
            Returns(200, "OK", model.Trigger{}))
    iamClient.PermissionContexts["handleGetTriggerDetail"] = resource.PermissionContext{
        Service:          IamServiceFcs,
        ResourceType:     IamResourceFcsTrigger,
        Action:           "GetTrigger",
        Resource:         "{triggerId}",
        ResourceFunction: getTriggerById,
    }
    // 检查触发器名称是否存在
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/groups/{groupId}/functions/{functionId}/triggers/action/exist").
            To(apiHandler.handleCheckTriggerExist).
            Doc("检查触发器名称是否存在").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Returns(200, "OK", nil))
    iamClient.PermissionContexts["handleCheckTriggerExist"] = resource.PermissionContext{
        LoginAccess: true,
    }

    // ---------- 自定义域名相关接口 ----------
    // 创建自定义域名
    apiAppV1Ws.Route(
        apiAppV1Ws.POST("/domains").
            To(apiHandler.handleCreateDomain))
    iamClient.PermissionContexts["handleCreateDomain"] = resource.PermissionContext{
        LoginAccess: true,
        RecordOps:   true,
    }
    // 更新自定义域名
    apiAppV1Ws.Route(
        apiAppV1Ws.PUT("/domains/{domainId}").
            To(apiHandler.handleUpdateDomain))
    iamClient.PermissionContexts["handleUpdateDomain"] = resource.PermissionContext{
        LoginAccess: true,
        RecordOps:   true,
    }
    // 删除自定义域名
    apiAppV1Ws.Route(
        apiAppV1Ws.DELETE("/domains/{domainId}").
            To(apiHandler.handleDeleteDomain))
    iamClient.PermissionContexts["handleDeleteDomain"] = resource.PermissionContext{
        LoginAccess: true,
        RecordOps:   true,
    }
    // 获取自定义域名列表
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/domains").
            To(apiHandler.handleGetDomainList))
    iamClient.PermissionContexts["handleGetDomainList"] = resource.PermissionContext{LoginAccess: true}
    // 获取自定义域名详情
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/domains/{domainId}").
            To(apiHandler.handleGetDomainDetail))
    iamClient.PermissionContexts["handleGetDomainDetail"] = resource.PermissionContext{LoginAccess: true}
    // 检查自定义域名是否存在
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/domains/action/exist").
            To(apiHandler.handleCheckDomainExist))
    iamClient.PermissionContexts["handleCheckDomainExist"] = resource.PermissionContext{
        LoginAccess: true,
        RecordOps:   true,
    }

    // ---------- 函数版本相关接口 ----------
    apiAppV1Ws.Route(
        apiAppV1Ws.POST("/groups/{groupId}/functions/{functionId}/versions").
            To(apiHandler.handleCreateVersion).
            Doc("创建版本").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Writes(model.FuncInfo{}).
            Returns(200, "OK", model.FuncInfo{}))
    iamClient.PermissionContexts["handleCreateVersion"] = resource.PermissionContext{LoginAccess: true, RecordOps: true}
    apiAppV1Ws.Route(
        apiAppV1Ws.DELETE("/groups/{groupId}/functions/{functionId}/versions/{versionName}").
            To(apiHandler.handleDeleteVersion).
            Doc("删除版本").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Param(apiAppV1Ws.PathParameter("versionName", "版本名称")).
            Returns(200, "OK", nil))
    iamClient.PermissionContexts["handleDeleteVersion"] = resource.PermissionContext{LoginAccess: true, RecordOps: true}
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/groups/{groupId}/functions/{functionId}/versions").
            To(apiHandler.handleGetVersionList).
            Doc("获取版本列表").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Returns(200, "OK", []model.FuncVersion{}))
    iamClient.PermissionContexts["handleGetVersionList"] = resource.PermissionContext{LoginAccess: true}

    // ---------- 函数别名相关接口 ----------
    apiAppV1Ws.Route(
        apiAppV1Ws.POST("/groups/{groupId}/functions/{functionId}/aliases").
            To(apiHandler.handleCreateAlias).
            Doc("创建别名").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Writes(model.FuncAlias{}).
            Returns(200, "OK", model.FuncAlias{}))
    iamClient.PermissionContexts["handleCreateAlias"] = resource.PermissionContext{LoginAccess: true, RecordOps: true}
    apiAppV1Ws.Route(
        apiAppV1Ws.PUT("/groups/{groupId}/functions/{functionId}/aliases/{aliasName}").
            To(apiHandler.handleUpdateAlias).
            Doc("更新别名").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Param(apiAppV1Ws.PathParameter("aliasName", "别名名称")).
            Writes(model.FuncAlias{}).
            Returns(200, "OK", model.FuncAlias{}))
    iamClient.PermissionContexts["handleUpdateAlias"] = resource.PermissionContext{LoginAccess: true, RecordOps: true}
    apiAppV1Ws.Route(
        apiAppV1Ws.DELETE("/groups/{groupId}/functions/{functionId}/aliases/{aliasName}").
            To(apiHandler.handleDeleteAlias).
            Doc("删除别名").
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Param(apiAppV1Ws.PathParameter("aliasName", "别名名称")).
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Returns(200, "OK", []model.FuncAlias{}))
    iamClient.PermissionContexts["handleDeleteAlias"] = resource.PermissionContext{LoginAccess: true, RecordOps: true}
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/groups/{groupId}/functions/{functionId}/aliases").
            To(apiHandler.handleGetAliasList).
            Doc("获取别名列表").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Returns(200, "OK", []model.FuncAlias{}))
    iamClient.PermissionContexts["handleGetAliasList"] = resource.PermissionContext{LoginAccess: true}
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/groups/{groupId}/functions/{functionId}/aliases/{aliasName}/exist").
            To(apiHandler.handleCheckAliasExist).
            Doc("检查别名是否存在").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Param(apiAppV1Ws.PathParameter("aliasName", "别名名称")).
            Returns(200, "OK", []model.FuncAlias{}))
    iamClient.PermissionContexts["handleCheckAliasExist"] = resource.PermissionContext{LoginAccess: true}
    // 给数据铁笼用的创建和更新函数的接口
    apiAppV1Ws.Route(
        apiAppV1Ws.POST("/groups/{groupId}/functions-ext").
            To(apiHandler.handleCreateFunctionExt).
            Doc("创建函数扩展接口").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Writes(model.FuncInfo{}).
            Returns(200, "OK", nil))
    iamClient.PermissionContexts["handleCreateFunctionExt"] = resource.PermissionContext{LoginAccess: true, RecordOps: true}
    apiAppV1Ws.Route(
        apiAppV1Ws.PUT("/groups/{groupId}/functions-ext/{functionId}").
            To(apiHandler.handleUpdateFunctionExt).
            Doc("更新函数扩展接口").
            Param(apiAppV1Ws.PathParameter("groupId", "应用id")).
            Param(apiAppV1Ws.PathParameter("functionId", "函数id")).
            Writes(model.UpdateModel{}).
            Returns(200, "OK", nil))
    iamClient.PermissionContexts["handleUpdateFunctionExt"] = resource.PermissionContext{LoginAccess: true, RecordOps: true}

    // ---------- 函数层相关接口 ----------
    apiAppV1Ws.Route(
        apiAppV1Ws.POST("/layers").
            To(apiHandler.handleCreateLayer).
            Doc("创建层").
            Writes(model.Layer{}).
            Returns(200, "OK", model.Layer{}))
    iamClient.PermissionContexts["handleCreateLayer"] = resource.PermissionContext{LoginAccess: true, RecordOps: true}
    apiAppV1Ws.Route(
        apiAppV1Ws.POST("/layers/{layerId}/versions").
            To(apiHandler.handleCreateLayerVersion).
            Doc("创建层版本").
            Writes(model.Layer{}).
            Returns(200, "OK", model.Layer{}))
    iamClient.PermissionContexts["handleCreateLayerVersion"] = resource.PermissionContext{LoginAccess: true, RecordOps: true}
    apiAppV1Ws.Route(
        apiAppV1Ws.DELETE("/layers/{layerId}/versions/{versionName}").
            To(apiHandler.handleDeleteLayerVersion).
            Doc("删除层版本").
            Param(apiAppV1Ws.PathParameter("layerId", "层id")).
            Param(apiAppV1Ws.PathParameter("versionName", "版本名称")).
            Returns(200, "OK", nil))
    iamClient.PermissionContexts["handleDeleteLayerVersion"] = resource.PermissionContext{LoginAccess: true, RecordOps: true}
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/layers").
            To(apiHandler.handleGetLayerList).
            Doc("获取层列表").
            Returns(200, "OK", []model.LayerListResult{}))
    iamClient.PermissionContexts["handleGetLayerList"] = resource.PermissionContext{LoginAccess: true}
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/layers/{layerId}/versions").
            To(apiHandler.handleGetLayerVersionList).
            Doc("获取层版本列表").
            Param(apiAppV1Ws.PathParameter("layerId", "层id")).
            Returns(200, "OK", []model.LayerVersionListResult{}))
    iamClient.PermissionContexts["handleGetLayerVersionList"] = resource.PermissionContext{LoginAccess: true}
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/compatible-layers").
            To(apiHandler.handleGetLayerRuntimeList).
            Doc("获取适配的层版本列表").
            Returns(200, "OK", []model.LayerVersionListResult{}))
    iamClient.PermissionContexts["handleGetLayerRuntimeList"] = resource.PermissionContext{LoginAccess: true}
    // 检查层名称是否存在
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/layers/action/exist").
            To(apiHandler.handleCheckLayerExist).
            Doc("检查层名称是否存在").
            Returns(200, "OK", nil))
    iamClient.PermissionContexts["handleCheckLayerExist"] = resource.PermissionContext{
        LoginAccess: true,
    }

    // ---------- 其他接口 ----------
    apiAppV1Ws.Route(
        apiAppV1Ws.POST("/functions/callback").
            To(apiHandler.handleCallback))
    iamClient.PermissionContexts["handleCallback"] = resource.PermissionContext{LoginAccess: true}
    apiAppV1Ws.Route(
        apiAppV1Ws.POST("/functions/url").
            To(apiHandler.handleGetUrl).
            Doc("获取函数url").
            Writes(model.UrlInfo{}).
            Returns(200, "OK", nil))
    iamClient.PermissionContexts["handleGetUrl"] = resource.PermissionContext{LoginAccess: true}
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/isSubnetUsed").
            To(apiHandler.handleIsSubnetUsed).
            Doc("判断子网是否被使用").
            Returns(200, "OK", nil))
    iamClient.PermissionContexts["handleIsSubnetUsed"] = resource.PermissionContext{LoginAccess: true}

    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/templates").
            To(apiHandler.handleGetTemplateList).
            Doc("获取模板").
            Returns(200, "OK", model.TemplateList{}))
    iamClient.PermissionContexts["handleGetTemplateList"] = resource.PermissionContext{LoginAccess: true}
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/template-scenes").
            To(apiHandler.handleGetTemplateScenes).
            Doc("获取模板场景").
            Returns(200, "OK", map[string]interface{}{}))
    iamClient.PermissionContexts["handleGetTemplateScenes"] = resource.PermissionContext{LoginAccess: true}
    apiAppV1Ws.Route(
        apiAppV1Ws.GET("/user-status").
            To(apiHandler.handleGetUserStatus).
            Doc("获取用户状态").
            Returns(200, "OK", nil))
    iamClient.PermissionContexts["handleGetUserStatus"] = resource.PermissionContext{LoginAccess: true}
    return apiAppV1Ws
}

func handleInternalError(response *restful.Response, err error) {
    logger.Debug(err)
    statusCode := http.StatusInternalServerError
    response.AddHeader("Content-Type", "text/plain")
    baseError, ok := err.(commonError.BaseError)
    if ok {
        if baseError.Reason().RequestId == "" {
            baseError.Reason().RequestId = response.Header().Get(commonFilter.RequestIdHeader)
        }
        logger.Debug(baseError.Reason().RequestId)
        _ = response.WriteErrorString(baseError.StatusCode(), baseError.Reason().ToString())
    } else {
        logger.Debug(response.Header().Get(commonFilter.RequestIdHeader))
        _ = response.WriteErrorString(statusCode, commonError.Error{Code: FcsErrorCodeSuffix + InternalServerErrorCode, Message: InternalServerErrorMessage, RequestId: response.Header().Get(commonFilter.RequestIdHeader)}.ToString())
    }
}

func currentUser(request *restful.Request) *resource.User {
    //user := request.Attribute(adapter.UserAttribute).(adapter.User)
    user := request.Attribute(resource.KeyCloakUserAttribute).(resource.User)
    return &user
}

func GetFcClient(api *APIHandler) (*k8s.FcClient, error) {

    config, err := clientcmd.BuildConfigFromFlags("", "")
    if err != nil {
        _ = logger.Error("get ClusterManager config error %v", err)
        return nil, commonError.InternalServerError(model.FunctionClientError, err.Error())
    }
    adminToken := utils.GetAdminToken()
    config.BearerToken = adminToken
    fcClient, err := k8s.NewClientFromConfig(config)
    if err != nil {
        _ = logger.Error("get fcClient error %v", err)
        return nil, commonError.InternalServerError(model.FunctionClientError, err.Error())
    }
    return fcClient, nil
}

func GetClientConfig(api *APIHandler) (*rest.Config, error) {
    config, err := clientcmd.BuildConfigFromFlags("", "")
    if err != nil {
        _ = logger.Error("get ClusterManager config error %v", err)
        return nil, commonError.InternalServerError(model.FunctionClientError, err.Error())
    }
    adminToken := utils.GetAdminToken()
    config.BearerToken = adminToken
    return config, nil
}
